﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.WebPages;
using SnippetBox.Core.Common.Caching;
using SnippetBox.Core.Common.Extensions;
using SnippetBox.Core.Data.Models;
using SnippetBox.Core.Data.Service;

namespace SnippetBox.Core.Web.Helpers {
    public static class MenuHelpers {
        public static IHtmlString RenderCategoryMenu(this HtmlHelper html) {
            CacheService cache = new CacheService();
            int currentCategoryId = 0;

            if (html.ViewContext.RouteData.Values.ContainsKey("categoryId"))  {
                currentCategoryId = html.ViewContext.RouteData.Values["categoryId"].ToString().AsInt();
            }

            return cache.Get("categoryMenu.{0}".FormatWith(currentCategoryId), () => { 
                CategoryService categoryService = new CategoryService();
                int currentTopCategoryId = categoryService.GetTopParentOf(currentCategoryId);

                var sb = new StringBuilder();
                var categories = categoryService.GetMainCategories();

                sb.AppendWithTabs("<ul>", 3);

                foreach (var category in categories) {
                    var isCurrent = currentTopCategoryId == category.CategoryId;
                    sb.AppendWithTabs("<li>", 4);
                    sb.AppendWithTabs("<a href=\"{0}\"{1}>{2}</a>".FormatWith(category.Link, isCurrent ? "class=\"current\"" : "", category.Name), 5);

                    if (currentTopCategoryId == category.CategoryId && category.ChildrenCategories != null) {
                        AppendSubCategories(sb, category, currentCategoryId, 5);
                    }

                    sb.AppendWithTabs("</li>", 4);
                }

                sb.AppendWithTabs("</ul>", 3);


                return new HtmlString(sb.ToString());
            });
        }

        private static void AppendSubCategories(StringBuilder sb, Category category, int currentCategoryId, int tabs) {
            var childrenCategories = category.ChildrenCategories.Where(cat => !cat.IsDeleted).ToList();

            if (!childrenCategories.Any())
                return;

            sb.AppendWithTabs("<ul>", tabs);

            foreach (var childrenCategory in childrenCategories.OrderBy(x => x.Name)) {
                var isCurrent = currentCategoryId == childrenCategory.CategoryId;

                sb.AppendWithTabs("<li>", tabs + 1);
                sb.AppendWithTabs("<a href=\"{0}\"{1}>{2}</a>".FormatWith(childrenCategory.Link, isCurrent ? "class=\"current\"" : "", childrenCategory.Name), tabs + 2);
                
                if (childrenCategory.ChildrenCategories != null) {
                    AppendSubCategories(sb, childrenCategory, currentCategoryId, tabs + 2);
                }

                sb.AppendWithTabs("</li>", tabs + 1);
            }

            sb.AppendWithTabs("</ul>", tabs);
        }

        private static void AppendWithTabs(this StringBuilder sb, string value, int tabs = 0) {
            for (int i = 0; i < tabs; i++) {
                sb.Append("    ");
            }
            sb.Append(value);
            sb.Append(Environment.NewLine);
        }
    }
}
